#include "Debug.h"
#include "PluginManager.h"

#include "modules/Gui.h"

#include "Offsets.h"
#include "RustLib.h"

DFHACK_PLUGIN("i18n");

namespace DFHack
{
  DBG_DECLARE(i18n, status, DebugCategory::LDEBUG);
  DBG_DECLARE(i18n, command, DebugCategory::LDEBUG);

  namespace I18n
  {
    color_ostream *i18n_out;
  }
}

using std::string;
using std::vector;
using namespace DFHack;
using namespace DFHack::I18n;

#define COMMAND_DESCRIPTION "I18n plugin for translating the game."
#define COMMAND_USAGE                         \
  COMMAND_DESCRIPTION                         \
  "\n\n"                                      \
  "Basic Commands:\n"                         \
  "i18n enable    Enable the translation.\n"  \
  "i18n disable   Disable the translation.\n" \
  "i18n toggle    Toggle the translation.\n"

DFhackDataExport bool i18n_enabling = false;
DFhackDataExport bool i18n_disabling = false;
DFhackDataExport bool i18n_enabled = false;

DFhackCExport void i18n_set_enabled(bool value)
{
  i18n_disabling = false;
  i18n_enabling = false;
  i18n_enabled = value;
  DEBUG(command, *I18n::i18n_out).print("[%s] Translation %s.\n", plugin_name, value ? "enabled" : "disabled");
}

command_result
command(color_ostream &out, vector<string> &parameters)
{
  if (parameters.size() == 0)
  {
    DEBUG(command, out).print("[%s] " COMMAND_USAGE, plugin_name);
    return CR_FAILURE;
  }

  string action = parameters[0];
  if (action == "toggle")
  {
    action = i18n_enabled ? "disable" : "enable";
  }

  if (action == "enable")
  {
    i18n_disabling = false;
    if (i18n_enabled)
    {
      DEBUG(command, out).print("[%s] Translation already enabled.\n", plugin_name);
      return CR_OK;
    }

    i18n_enabling = true;
    DEBUG(command, out).print("[%s] Enabling translation...\n", plugin_name);
  }
  else if (action == "disable")
  {
    i18n_enabling = false;
    if (!i18n_enabled)
    {
      DEBUG(command, out).print("[%s] Translation already disabled.\n", plugin_name);
      return CR_OK;
    }

    i18n_disabling = true;
    DEBUG(command, out).print("[%s] Disabling translation...\n", plugin_name);
  }
  else
  {
    out.printerr("error: unknown command: \"%s\" for \"%s\"\n", parameters[0].c_str(), plugin_name);
    return CR_FAILURE;
  }

  return CR_OK;
}

DFhackCExport command_result plugin_init(color_ostream &out, vector<PluginCommand> &commands)
{
  DEBUG(status, out).print("[%s] initializing...\n", plugin_name);
  i18n_out = &out;

  DEBUG(status, out).print("[%s] searching for offsets...\n", plugin_name);
  if (!Offsets::searchAll(out))
    return CR_FAILURE;

  DEBUG(status, out).print("[%s] starting services...\n", plugin_name);
  i18n_rust_init();

  commands.push_back(PluginCommand(plugin_name, COMMAND_DESCRIPTION, command, Gui::anywhere_hotkey, COMMAND_USAGE));

  return CR_OK;
}

DFhackCExport command_result plugin_shutdown(color_ostream &out)
{
  DEBUG(status, out).print("[%s] shutting down...\n", plugin_name);

  return CR_OK;
}

DFhackCExport void i18n_log(const char *msg)
{
  DEBUG(status, *I18n::i18n_out).print("%s\n", msg);
};

DFhackCExport void i18n_err(const char *msg)
{
  DEBUG(status, *I18n::i18n_out).printerr("%s\n", msg);
};

DFhackCExport string *i18n_get_screen()
{
  static string i18n_screen;

  vector<string> screens = Gui::getCurFocus(true);
  i18n_screen = join_strings(";", Gui::getCurFocus(true));

  return &i18n_screen;
}
